package XunChunCPU.Accelerator

import chisel3._

// 16个一位相加的华莱士树
class WallaceTree16 extends Module{
    val io = IO(new Bundle{
        val N = Input(UInt(16.W))
        val S = Output(Bool())
        val C = Output(Bool())
        val Cin = Input(Vec(15,Bool()))
        val Cout = Output(Vec(15,Bool()))
    })
    // *************************************************************
    // 第一层: 16 in (5 adder)
    val adder0 = Module(new Adder)
    val adder1 = Module(new Adder)
    val adder2 = Module(new Adder)
    val adder3 = Module(new Adder)
    val adder4 = Module(new Adder)

    adder0.io.A := io.N(0)
    adder0.io.B := io.N(1)
    adder0.io.Cin := io.N(2)

    adder1.io.A := io.N(3)
    adder1.io.B := io.N(4)
    adder1.io.Cin := io.N(5)

    adder2.io.A := io.N(6)
    adder2.io.B := io.N(7)
    adder2.io.Cin := io.N(8)

    adder3.io.A := io.N(9)
    adder3.io.B := io.N(10)
    adder3.io.Cin := io.N(11)
    
    adder4.io.A := io.N(12)
    adder4.io.B := io.N(13)
    adder4.io.Cin := io.N(14)
    // *************************************************************
    // 第二层: 11 in (4 adder)
    val adder5 = Module(new Adder)
    val adder6 = Module(new Adder)
    val adder7 = Module(new Adder)
    val adder8 = Module(new Adder)

    adder5.io.A := io.N(15)
    adder5.io.B := adder0.io.S
    adder5.io.Cin := adder1.io.S
    
    adder6.io.A := adder2.io.S
    adder6.io.B := adder3.io.S
    adder6.io.Cin := adder4.io.S

    adder7.io.A := io.Cin(0)
    adder7.io.B := io.Cin(1)
    adder7.io.Cin := io.Cin(2)
    
    adder8.io.A := io.Cin(3)
    adder8.io.B := io.Cin(4)
    adder8.io.Cin := false.B
    // *************************************************************
    // 第三层: 8 in (3 adder)
    val adder9 = Module(new Adder)
    val adder10 = Module(new Adder)
    val adder11 = Module(new Adder)

    adder9.io.A := adder5.io.S
    adder9.io.B := adder6.io.S
    adder9.io.Cin := adder7.io.S

    adder10.io.A := adder8.io.S
    adder10.io.B := io.Cin(5)
    adder10.io.Cin := io.Cin(6)
    
    adder11.io.A := io.Cin(7)
    adder11.io.B := io.Cin(8)
    adder11.io.Cin := false.B
    // *************************************************************
    // 第四层: 6 in (2 adder)
    val adder12 = Module(new Adder)
    val adder13 = Module(new Adder)

    adder12.io.A := adder9.io.S
    adder12.io.B := adder10.io.S
    adder12.io.Cin := adder11.io.S

    adder13.io.A := io.Cin(9)
    adder13.io.B := io.Cin(10)
    adder13.io.Cin := io.Cin(11)
    // *************************************************************
    // 第5层: 4 in (1 adder)
    val adder14 = Module(new Adder)
    
    adder14.io.A := adder12.io.S
    adder14.io.B := adder13.io.S
    adder14.io.Cin := io.Cin(12)
    // *************************************************************
    // 第6层: 3 in (1 adder)
    val adder15 = Module(new Adder)
    
    adder15.io.A := adder14.io.S
    adder15.io.B := io.Cin(13)
    adder15.io.Cin := io.Cin(14)

    // *************************************************************
    // 模块整体的输出
    io.Cout(0) := adder0.io.Cout
    io.Cout(1) := adder1.io.Cout
    io.Cout(2) := adder2.io.Cout
    io.Cout(3) := adder3.io.Cout
    io.Cout(4) := adder4.io.Cout
    io.Cout(5) := adder5.io.Cout
    io.Cout(6) := adder6.io.Cout
    io.Cout(7) := adder7.io.Cout
    io.Cout(8) := adder8.io.Cout
    io.Cout(9) := adder9.io.Cout
    io.Cout(10) := adder10.io.Cout
    io.Cout(11) := adder11.io.Cout
    io.Cout(12) := adder12.io.Cout
    io.Cout(13) := adder13.io.Cout
    io.Cout(14) := adder14.io.Cout

    io.C := adder15.io.Cout
    io.S := adder15.io.S
}